# coding: utf8
"""
获取一个照片集
"""

import os, requests, re, threading  # 线程
from HTTP.Downloader1024.common.functions import getHtml
from HTTP.Downloader1024.common.Logging_Model import *
from sys import stdout


header = {'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'}
path = os.getcwd()
lock = threading.Lock()


def photoURL(text):
    """
    The function is that get URL list from a HTML.

    :param text:
    :return: listURL, HTML name
    """
    _h, text = text
    listURL = re.findall(r'<img src="(.*?)" border="0"', text)
    if len(listURL) is 0:
        print("The HTML has not URL for photo.")
        return 'Error'
    name = re.findall(r'<span id="subject_tpc">(.*?)</span>', text)[0]
    with open('./Support/photoURL.txt', mode='w', encoding='utf8') as f:
        f.write(f'{name}\n')
        for i in listURL:
            f.write(f'{i}\n')
    return listURL, name


def getAPhoto(photo_url, gallery, for_times):
    """
    Download1024 photo for the gallery.
    :param for_times: A times in cycle.
    :param photo_url: A url in internet for a photo.
    :param gallery: The photo belong to the gallery.
    :return:successful or error.
    """
    global photo, s_code
    # 终止已存在的下载
    if os.path.exists(f'{gallery}/{photo_url[-12:]}'):
        stdout.write('\r')
        stdout.flush()
        stdout.write(f"{for_times}::The file ({photo_url[-12:]}) is already Exist.")
        stdout.flush()
        return 'exist'
    n = 3
    while n:
        try:
            photo = requests.get(photo_url, headers=header, timeout=20)  # 获取图片
            s_code = photo.status_code
            break
        except:
            n -= 1
            if n == 0:
                logger.error(f'{photo_url[-12:]}写入失败(PhotoURL:{photo_url})')
                Traceback()
                return 'Error'
    # 写入文件
    try:
        with open(f'{gallery}/{photo_url[-12:]}', 'wb', encoding='utf8') as p:
            p.write(photo.content)
    except: pass
    if os.path.exists(f'{gallery}/{photo_url[-12:]}'):
        stdout.write('\r')
        stdout.flush()
        stdout.write(f'{for_times}::{photo_url[-12:]}写入成功')
        stdout.flush()
        return 'successful'


def writeAll(urllist, name, dir_type):
    """
    Create a folder for this gallery and download those images.
    :param dir_type:
    :param urllist: some url of photos in the list.
    :param name: The photo gallery's name.
    :return: Successful or Error.
    """
    exist_n = 0
    lock.acquire()
    try:
        if not os.path.exists('./photos'): os.mkdir('./photos')
        if not os.path.exists(f'./photos/{dir_type}'): os.mkdir(f'./photos/{dir_type}')
        if not os.path.exists(f'./photos/{dir_type}/{name}'): os.mkdir(f'./photos/{dir_type}/{name}')
    except FileExistsError: logger.error(f'[WinError 183] 当文件已存在时，无法创建该文件。: ./photos/{dir_type}/{name}')
    lock.release()
    # 缩进问题一定要注意啊
    name = f'./photos/{dir_type}/{name}'
    print('path', end=':')
    print(f'{path}{name[1:]}')
    for_times = 0
    for url in urllist:
        for_times += 1
        if getAPhoto(url, name, for_times) is 'exist':
            exist_n += 1
    print('')
    return exist_n


def threadingWrite(_list_photo_url, photo_name, dir_type):
    """

    :param dir_type: j
    :param _list_photo_url: A list for Photo.
    :param photo_name: A name of Directory about the download photos.
    :return:
    """
    logger.info('GetPhotos_多线程开始。。。')
    global _f
    exist = writeAll(_list_photo_url, photo_name, dir_type)  # list, name
    #
    for _f in os.walk(f'{path}/photos/{dir_type}/{photo_name}'): pass  # 查询文件夹文件数
    if (len(_f[2]) is not exist) or (len(_list_photo_url) - len(_f[2]) is not 0): pass
    # logger.info(f'{photo_name}:成功下载{len(_f[2])}个，下载失败{len(_list_photo_url)-len(_f[2])},其中已存在{exist}个')
    # removeHandler()
    return f'{photo_name}:成功下载{len(_f[2])}个，下载失败{len(_list_photo_url)-len(_f[2])},其中已存在{exist}个'


def _type(url):
    _t = ''
    for u in url.split('/'):
        if u == '14' or u == '21':
            _t = '唯美写真'
            break
        elif u == '106':
            _t = '漫画图集'
            break
        else: _t = '其他'
    return _t


def main(url):
    """ The function can finish the script all of things.
        Convenient for other script calls.
        """
    #
    global more
    t = _type(url)
    print(t)
    html = getHtml(url)
    if html is 'Error':
        logger.error(f'GetHtmlError:{url}')
        return 'getHtmlError'
    #
    listPhotoURL = photoURL(html)
    if listPhotoURL is 'Error':
        logging.error('ListPhoto Error: The HTML in URL has not photos.')
        # removeHandler()
        return 'ListPhoto Error'
    logger.info(f'正在下载：{listPhotoURL[1]}({url})')
    #
    PhotoURL = listPhotoURL[0][0::2], listPhotoURL[0][1::2]
    for _url in PhotoURL:
        more = threading.Thread(target=threadingWrite, args=(_url, listPhotoURL[1], t))
        more.start()
    more.join()


if __name__ == '__main__':
    # URL = 'http://w2.xggfgczh781.pw/pw/html_data/14/1901/3857856.html'
    URL = 'http://q1.0e8c2c0f.pw/pw/html_data/14/1911/4440842.html'  # 2019-11-20
    main(URL)
